package com.duobaoyu.dby.supply.biz.strategy.message.order.confirm;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.toolkit.ObjectUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.duobaoyu.dby.channel.adapter.enums.BizMessageTypeEnum;
import com.duobaoyu.dby.channel.adapter.enums.ChannelCodeEnum;
import com.duobaoyu.dby.channel.strategy.supply.impl.real.ordering.callback.OrderingOrderCallback;
import com.duobaoyu.dby.common.mybatis.config.IdGeneratorSnowflake;
import com.duobaoyu.dby.supply.biz.enums.OrderParentTypeEnum;
import com.duobaoyu.dby.supply.biz.producer.SupplyChainMQProducer;
import com.duobaoyu.dby.supply.biz.strategy.message.order.base.BaseOrderAsyncHandler;
import com.duobaoyu.dby.supply.common.biz.bo.message.ChannelMessageBO;
import com.duobaoyu.dby.supply.db.entity.order.Order;
import com.duobaoyu.dby.supply.db.entity.order.OrderConsignee;
import com.duobaoyu.dby.supply.db.entity.order.OrderProduct;
import com.duobaoyu.dby.supply.db.repository.order.OrderConsigneeRepository;
import com.duobaoyu.dby.supply.db.repository.order.OrderProductRepository;
import com.duobaoyu.dby.supply.db.repository.order.OrderRepository;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.jetbrains.annotations.NotNull;
import org.springframework.stereotype.Component;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionCallbackWithoutResult;
import org.springframework.transaction.support.TransactionTemplate;

import java.util.List;
import java.util.Set;

/**
 * @author fengshaoyu
 */
@Slf4j
@Component
@RequiredArgsConstructor
public class OrderingConfirmChangeAsyncHandler extends BaseOrderAsyncHandler {

	private final OrderRepository orderRepository;
	private final TransactionTemplate transactionTemplate;
	private final IdGeneratorSnowflake idGeneratorSnowflake;
	private final SupplyChainMQProducer supplyChainMQProducer;
	private final OrderProductRepository orderProductRepository;
	private final OrderConsigneeRepository orderConsigneeRepository;

	@Override
	protected Set<String> channelCodes() {
		return Sets.newHashSet(ChannelCodeEnum.ORDERING.getValue());
	}

	@Override
	protected Set<Integer> bizMessageTypes() {
		return Sets.newHashSet(BizMessageTypeEnum.CONFIRM_ORDER.getValue());
	}

	@Override
	protected Boolean executeHandler(ChannelMessageBO channelMessage, Object beforeResult) {
		OrderingOrderCallback orderingOrderCallback = JSON.parseObject(channelMessage.getOriginalMessage(), OrderingOrderCallback.class);
		Order order = orderRepository.getOne(Wrappers.<Order>lambdaQuery().eq(Order::getChannelTradeOrderSn, orderingOrderCallback.getOrderNum())
				.eq(Order::getChannelCode, channelMessage.getChannelCode()));

		if (ObjectUtils.isEmpty(order)) {
			log.info("message:{},channelCode:{},data:{}","确认回调失败",channelMessage.getChannelCode(),JSON.toJSONString(channelMessage));
			return Boolean.FALSE;
		}

		this.orderStateCheck(order);

		List<OrderProduct> orderProductList = orderProductRepository.list(Wrappers.<OrderProduct>lambdaQuery().eq(OrderProduct::getOrderSn, order.getOrderSn()));
		OrderConsignee orderConsignee = orderConsigneeRepository.getOne(Wrappers.<OrderConsignee>lambdaQuery().eq(OrderConsignee::getOrderSn, order.getOrderSn()));

		List<Order> orderList = Lists.newArrayList();
		List<OrderConsignee> orderConsigneeList = Lists.newArrayList();
		List<OrderProduct> orderProductCopyList = Lists.newArrayList();

		for (OrderingOrderCallback.PkgInfo pkgInfo : orderingOrderCallback.getPkgInfoList()) {
			List<OrderProduct> orderProductCopy = Lists.newArrayList();
			//商品信息
			for (OrderingOrderCallback.PkgInfo.ItemInfo itemInfo : pkgInfo.getItemInfoList()) {
				for (OrderProduct orderProduct:orderProductList) {
					if(itemInfo.getSkuId().equals(orderProduct.getChannelSkuCode()) && itemInfo.getItemId().equals(orderProduct.getChannelProductCode())){
						OrderProduct clone = orderProduct.clone();
						clone.setSkuNum(itemInfo.getNumber());
						orderProductCopy.add(clone);
					}
				}

				reckon(orderProductList);
				Order clone = order.clone();
				clone.setChannelOrderSn(pkgInfo.getPkgNo());
				clone.setChannelTradeOrderSn(orderingOrderCallback.getOrderNum());
				clone.setAfterSalesAllowed(Boolean.TRUE);
				Order orderOne = createOrder(clone, orderProductList);
				orderProductCopy.forEach(orderProduct -> {
					orderProduct.setId(idGeneratorSnowflake.snowflakeId());
					orderProduct.setOrderSn(orderOne.getOrderSn());
				});
				OrderConsignee orderConsigneeClone = orderConsignee.clone();
				orderConsigneeClone.setId(idGeneratorSnowflake.snowflakeId());
				orderConsigneeClone.setOrderSn(clone.getOrderSn());

				orderList.add(orderOne);
				orderProductCopyList.addAll(orderProductCopy);
				orderConsigneeList.add(orderConsigneeClone);
			}
		}

		transactionTemplate.execute(new TransactionCallbackWithoutResult() {
			@Override
			protected void doInTransactionWithoutResult(@NotNull TransactionStatus transactionStatus) {
				orderRepository.saveBatch(orderList);
				orderProductRepository.saveBatch(orderProductCopyList);
				orderConsigneeRepository.saveBatch(orderConsigneeList);
				orderRepository.update(Wrappers.<Order>lambdaUpdate().set(Order::getParentType, OrderParentTypeEnum.BEFORE_SPLIT.getValue())
						.eq(Order::getId, order.getId()));
			}
		});
		supplyChainMQProducer.orderAlterSend(order.getSupplyTradeSn(), order.getServerName());
		return Boolean.TRUE;
	}
}
